type
  TSimpleClient = class(TObject)
    DNS,
      Name: string;
    ListLink: Integer;
    Thread: Pointer;
  end;

TFServer = class(TForm)
  //Creacion de todos los componentes
private
    { Private declarations }
  public
    { Public declarations }
    Clients: TList;
    procedure UpdateBindings;
    procedure UpdateClientList;
    procedure BroadcastValue(dat: integer);
  end;

var
  FServer: TFServer;
implementation

{$IFDEF MSWINDOWS}{$R *.dfm}{$ELSE}{$R *.xfm}{$ENDIF}
uses
  IdSocketHandle, IdThread, UHilo;


procedure TFServer.UpdateBindings;
var
  Binding: TIdSocketHandle;
begin
  tcpServer.DefaultPort := StrToInt(EPort.Text);
  tcpServer.Bindings.Clear;
  Binding := tcpServer.Bindings.Add;
  Binding.Port := StrToInt(EPort.Text);
end;

procedure TFServer.BroadcastValue(dat: integer);
var
   List: TList;
   count: integer;
begin
   List := FServer.tcpServer.Threads.LockList;
   //Lo anterior me devueve toda la lista de lsoc lientes
   //y list:items[i] es un cliente especifico
   try
      for Count := 0 to List.Count - 1 do
      begin
         try
            TIdPeerThread(List.Items[Count]).Connection.WriteLn(IntToStr(dat));//Esto es un cliente
         except
            TIdPeerThread(List.Items[Count]).Stop;
      end;
   end;
   finally
      tcpServer.Threads.UnlockList;
   end;
end;


procedure TFServer.FormCreate(Sender: TObject);
begin
   Clients := TList.Create;
   UpdateBindings;
end;

procedure TFServer.BConectarClick(Sender: TObject);
begin
   tcpServer.Active := not tcpServer.Active;
   BConectar.Down := tcpServer.Active;
end;

procedure TFServer.tcpServerConnect(AThread: TIdPeerThread);
var
   Client: TSimpleClient;
begin
   //AThread.Connection.WriteLn('Bienvenido al servidor');
   //AThread.Connection.WriteLn('Encargado de entregar seņales...');
   //AThread.Connection.WriteLn('Por favor ingrese su Login: ');
   Client:= TSimpleClient.Create;
   Client.DNS:= AThread.Connection.LocalName;
   Client.Name:= 'LoginInit';
   Client.ListLink:= LBClients.Items.Count;
   Client.Thread:= AThread;
   LBClients.Items.Add(Client.Name);
   AThread.Data := Client;
   Clients.Add(Client);
end;


procedure TFServer.tcpServerDisconnect(AThread: TIdPeerThread);
var
  Client: TSimpleClient;
begin
  Client := Pointer(AThread.Data);
  Clients.Delete(Client.ListLink);
  LBClients.Items.Delete(LBClients.Items.IndexOf(Client.Name));
  Client.Free;
  AThread.Data := nil;
end;

procedure TFServer.UpdateClientList;
var
  Count: Integer;
begin
   for Count := 0 to LBClients.Items.Count - 1 do
   begin
      if Count < Clients.Count then
         LBClients.Items.Strings[Count] :=
               TSimpleClient(Clients.Items[Count]).Name; //Esto es una forma de sacar los nombres de los clieents
   end;
  //Clients.Items[Count] es un puntero al cliente Count
end;

procedure TFServer.tcpServerExecute(AThread: TIdPeerThread);
var
  Client: TSimpleClient;
  Msg: string;
begin
   Msg:= AThread.Connection.ReadLn;
   Client:= Pointer(AThread.Data);
   Client.Name:= Msg;
   UpdateClientList;
   //AThread.Connection.WriteLn('Ha sido logiado como: '+Msg);
end;

procedure TFServer.btnClientsClick(Sender: TObject);
begin
  UpdateClientList;
end;


procedure TFServer.btnKillClientClick(Sender: TObject);
var
   Client: TSimpleClient;
begin
   Client := Clients.Items[LBClients.ItemIndex];
   TIdPeerThread(Client.Thread).Connection.WriteLn('Lo he desconectado [Loca]');
   TIdPeerThread(Client.Thread).Connection.Disconnect;
   Clients.Delete(LBClients.ItemIndex);
   LBClients.Items.Delete(LBClients.ItemIndex);
end;


procedure TFServer.SpeedButton1Click(Sender: TObject);
begin
   case EPortFisico.ItemIndex of
      0:  Hilo.Create(2, StrToInt('$03F8'), StrToInt(FServer.EPort.Text));
      1:  Hilo.Create(2, StrToInt('$02F8'), StrToInt(FServer.EPort.Text));
   end;
end;

end.

    Source: geocities.com/tiger928rs/txt

               ( geocities.com/tiger928rs)